# coding=utf-8
import falcon
from playhouse.shortcuts import model_to_dict
from falcon.media.validators import jsonschema

from db.models import Action
from db.base import db

post_json_schema = {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "description": "The name of the task or command."
        },
        "category": {
            "type": "string",
            "description": "The category of the task or command.",
            "enum": ["shell", "python"]  # 假设只有 "shell" 和 "other" 两种类别
        },
        "exec": {
            "type": "string",
            "description": "The path to the executable."
        },
        "content": {
            "type": "string",
            "description": "The content or command to be executed."
        },
        "timeout": {
            "type": "integer",
            "description": "The timeout for the command execution in seconds.",
            "default": 30,
            "minimum": 0  # 确保 timeout 是一个非负数
        },
        "retry": {
            "type": "integer",
            "description": "The number of retries for the command execution.",
            "default": 0,
            "minimum": 0  # 确保 retry 是一个非负数
        },
        "desc": {
            "type": "string",
            "description": "The description of the task or command.",
            "default": ""  # 如果未提供，则默认为空字符串
        }
    },
    "required": ["name", "category", "exec", "content"],
    "additionalProperties": False  # 不允许有额外的未定义属性
}

update_json_schema = {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "description": "The name of the task or command."
        },
        "exec": {
            "type": "string",
            "description": "The path to the executable."
        },
        "content": {
            "type": "string",
            "description": "The content or command to be executed."
        },
        "timeout": {
            "type": "integer",
            "description": "The timeout for the command execution in seconds.",
            "default": 30,
            "minimum": 0  # 确保 timeout 是一个非负数
        },
        "retry": {
            "type": "integer",
            "description": "The number of retries for the command execution.",
            "default": 0,
            "minimum": 0  # 确保 retry 是一个非负数
        },
        "desc": {
            "type": "string",
            "description": "The description of the task or command.",
            "default": ""  # 如果未提供，则默认为空字符串
        }
    },
    "required": ["name", "exec", "content"],
    "additionalProperties": False  # 不允许有额外的未定义属性
}


class ActionResource:
    def on_get(self, req: falcon.Request, resp: falcon.Response, resource_id: int = 0):
        if resource_id == 0:
            page = req.get_param_as_int("page", default=1)
            page_size = req.get_param_as_int("page_size", default=10)
            total = Action.select().count()

            actions = Action.select().order_by(Action.created_time).paginate(page, page_size)
            resp.media = {
                "total": total,
                "page": page,
                "page_size": page_size,
                "data": [model_to_dict(i) for i in actions]
            }
        else:
            resource = Action.get_by_id(resource_id)
            resp.media = model_to_dict(resource)

    @jsonschema.validate(req_schema=post_json_schema)
    def on_post(self, req: falcon.Request, resp: falcon.Response):
        data = req.get_media()
        new_resource = Action()
        new_resource.name = data.get("name")
        new_resource.category = data.get("category")
        new_resource.exec = data.get("exec")
        new_resource.content = data.get("content")
        new_resource.timeout = data.get("timeout", 30)
        new_resource.retry = data.get("retry", 0)
        new_resource.desc = data.get("desc")
        new_resource.save()

    @jsonschema.validate(req_schema=update_json_schema)
    def on_patch(self, req: falcon.Request, resp: falcon.Response, resource_id: int):
        try:
            resource = Action.get_by_id(resource_id)
        except Action.DoesNotExist:
            raise falcon.HTTPBadRequest(title="Resource not exist", description=resource_id)

        data = req.get_media()
        resource.name = data.get("name")
        resource.exce = data.get("exec")
        resource.content = data.get("content")
        resource.timeout = data.get("timeout", 30)
        resource.retry = data.get("retry", 0)
        resource.desc = data.get("desc", "")
        resource.save()

    def on_delete(self, req: falcon.Request, resp: falcon.Response, resource_id: int):
        with db.atomic():
            Action.delete_by_id(resource_id)
